#ifndef STACKTREE_H
#define STACKTREE_H

#include "ErrorType.h"
#define MAXSIZE 1000

#define TRUE 1
#define FALSE 0

typedef int bool;
typedef int ElementType;
typedef struct TreeNode *BinTree;
typedef BinTree Position;
struct TreeNode
{
    // ElementType Data;
    ElementType num;
    BinTree Left;
    BinTree Right;
};

typedef BinTree StkElementType;
typedef struct SNode *Stack;
struct SNode{
    StkElementType BT;
    struct SNode *Next;
};

// Create an empty stack the largest length of which is MAXSIZE.
Stack CreateStack();

// Judge whether stack S is full or not.
bool StackFull(Stack PtrS);

// Judge whether Stack S is empty or not.
bool StackEmpty(Stack S);

// Push element item into the stack.
bool Push(Stack *S, StkElementType BT);

// Delete and return the top element of stack.
StkElementType Pop(Stack *S);

// Return the length of the stack.
int StackLength(Stack S);

// Return the top element of the stack.
StkElementType getTop(Stack S);

// Clear the elements stored in the stack
bool ClearStack(Stack S);

// Destroy the stack
bool DestroyStack(Stack S);

// void ShowList(Stack S);
#endif

Stack CreateStack(){
    Stack PtrS = (Stack) malloc(sizeof( struct SNode ));
    PtrS->Next = NULL;
    return PtrS;
}

bool StackFull(Stack PtrS){
    int i = StackLength(PtrS);
    if(i == MAXSIZE)
        return TRUE;
    else
        return FALSE;
}

bool StackEmpty(Stack S){
    if(!(S->Next))
        return TRUE;
    else
        return FALSE;
}

bool Push(Stack *PtrS, StkElementType BT){
    if(StackFull(*PtrS) == TRUE){
        printf("Operation Failed!\nError Code %02x!\n",OVERFLOW);
        return FALSE;
    }
    else{
        Stack p = CreateStack();
        p->BT = BT;
        p->Next = PtrS;
        *PtrS = p;
        return TRUE;
    }
}

StkElementType Pop(Stack *PtrS){
    if(StackEmpty(*PtrS) == TRUE){
        printf("Operation Failed!\nError Code %02x!\n",INVALID);
        return NULL;
    }
    else{
        Stack p = *PtrS;
        StkElementType BTree = p->BT;
        *PtrS = p->Next;
        free(p);
        return BTree;
    }
}

int StackLength(Stack PtrS) {
    int i;
    for(i = 0; PtrS != NULL ; PtrS = PtrS->Next, i++);
    return i;
}

StkElementType getTop(Stack S) {
    if(StackEmpty(S) == TRUE){
        printf("Operation Failed!\nError Code %02x!\n",INVALID);
        return 0;
    }
    else{
        return S->BT;
    }
}

bool ClearStack(Stack S) {
    struct SNode *temp = S;
    while (S != NULL)
    {
        S = S->Next;
        temp->BT = NULL;
        temp = S;
    }

    if (S == NULL)
    {
        return TRUE;
    }
    else return FALSE;
}

bool DestroyStack(Stack S) {
    struct SNode *temp = S;
    while (S != NULL)
    {
        S = S->Next;
        free(temp);
        temp = S;
    }

    if (S == NULL)
    {
        return TRUE;
    }
    else return FALSE;
}
